<template>
    <a-row :gutter="[20]" class="videoBox">
        <a-col :span="7">
            <span style="color: red; white-space: nowrap"
                >注：
                单个通道可选择窗口进行播放，勾选多个通道默认从选择的窗口往后播放。</span
            >
            <a-card title="控制台">
                <div slot="extra">
                    <a-select
                        slot="extra"
                        style="width: 150px;"
                        v-model="modelType"
                    >
                        <a-select-option value="1">流地址播放</a-select-option>
                        <a-select-option value="2">工程化播放</a-select-option>
                    </a-select>
                </div>
                <a-form
                    v-if="modelType === '1'"
                    :labelCol="{ span: 4 }"
                    :wrapperCol="{ span: 18 }"
                >
                    <span style="color: red; white-space: nowrap"
                        >注： 可选择窗口进行播放</span
                    >
                    <a-form-item label="通道ID">
                        <a-input
                            v-model="channel"
                            placeholder="100001$1$0$0"
                        ></a-input>
                    </a-form-item>
                    <a-form-item label="rtsp地址">
                        <a-input v-model="path" placeholder="rtsp://"></a-input>
                    </a-form-item>
                    <a-form-item label="是否重定向">
                        <a-switch
                            checked-children="是"
                            un-checked-children="否"
                            v-model="isRedirect"
                        ></a-switch>
                        <a-button style="float: right;" @click="changeUrl"
                            >播放视频</a-button
                        >
                    </a-form-item>
                    <div v-if="videoType === 'video1'">
                        对讲功能：
                        <a-form-item label="通道ID">
                            <a-input
                                v-model="channel2"
                                placeholder="100001$1$0$0"
                            ></a-input>
                        </a-form-item>
                        <a-form-item label="对讲rtsp">
                            <a-input
                                v-model="path3"
                                placeholder="请输入rtsp地址"
                            ></a-input>
                        </a-form-item>
                        <a-form-item label="对讲参数">
                            <a-input
                                v-model="talkParam"
                                placeholder="逗号拼接: 0,8,8000"
                            ></a-input>
                            <span style="white-space: nowrap; color: blue;"
                                >按顺序输入audioType, audioBit,
                                sampleRate三个参数</span
                            >
                            <a-button style="float: right;" @click="talkByUrl"
                                >开始对讲</a-button
                            >
                        </a-form-item>
                    </div>
                    <div v-if="videoType === 'video2'">
                        录像下载功能：
                        <a-form-item label="录像下载">
                            <a-input
                                v-model="path4"
                                placeholder="请输入下载rtsp"
                            ></a-input>
                            <a-button
                                @click="downloadRecord"
                                style="float: right;"
                                >下载</a-button
                            >
                        </a-form-item>
                    </div>
                </a-form>
                <div v-if="modelType === '2'" style="position: relative">
                    <a-button
                        style="position: absolute; right: 0; top: 0"
                        v-if="videoType === 'video1'"
                        @click="realByChannel"
                        size="small"
                        type="dashed"
                        >实时预览</a-button
                    >
                    <a-button
                        style="position: absolute; right: 0; top: 0"
                        v-if="videoType === 'video2'"
                        @click="playbackByChannel"
                        size="small"
                        type="dashed"
                        >录像回放</a-button
                    >
                    <div :style="`height: 500px; overflow: auto;`">
                        <a-tree
                            v-model="checkedKeys"
                            checkable
                            show-icon
                            :expanded-keys="expandedKeys"
                            :selected-keys="selectedKeys"
                            :replace-fields="replaceFields"
                            :tree-data="treeData"
                            @expand="onExpand"
                            @select="onSelect"
                        >
                            <template slot="icon" slot-scope="record">
                                <img :src="record.iconType" alt="" />
                            </template>
                        </a-tree>
                    </div>
                </div>
                <!-- 云台容器 -->
                <a-collapse
                    v-if="videoType === 'video1'"
                    v-model="panClloapse"
                    class="pan-clloapse"
                >
                    <a-collapse-panel key="1" header="云台控制栏">
                        <div id="dhplayer-pan-tilt"></div>
                    </a-collapse-panel>
                </a-collapse>
            </a-card>
        </a-col>
        <a-col :span="17">
            <div>
                <a-radio-group
                    v-model="videoType"
                    button-style="solid"
                    size="large"
                >
                    <a-radio-button value="video1">
                        实时视频
                    </a-radio-button>
                    <a-radio-button value="video2">
                        录像回放
                    </a-radio-button>
                </a-radio-group>
                <span style="display: inline-block; float: right;">
                    <span style="margin-left: 20px;"
                        >窗口数量：<a-input
                            type="number"
                            :min="0"
                            v-model="divisionNum"
                            :max="64"
                            style="width: 100px"
                            @change="changeDivision"
                        ></a-input
                    ></span>
                    <span style="margin-left: 20px;"
                        >选择窗口号：<a-input
                            type="number"
                            :min="0"
                            :max="maxSnum"
                            v-model="currentNum"
                            style="width: 100px"
                            @change="chooseWindow"
                        ></a-input
                    ></span>
                    <span style="margin-left: 20px;" v-if="modelType === '2'">
                        <a-select
                            v-model="streamType"
                            style="margin-bottom: 10px"
                            dropdownClassName="streamTypeClass"
                            :options="streamTypeOption"
                        />
                        <a-select
                            v-model="recordSource"
                            v-if="videoType === 'video2'"
                            dropdownClassName="recordSourceClass"
                            :options="[
                                {
                                    value: 2,
                                    label: '设备录像'
                                },
                                {
                                    value: 3,
                                    label: '中心录像'
                                }
                            ]"
                        />
                        <a-range-picker
                            v-if="videoType === 'video2'"
                            v-model="timeRanger"
                            style="width: 335px;"
                            dropdownClassName="datePickerClass"
                            :show-time="{
                                hideDisabledOptions: true,
                                defaultValue: [
                                    moment('00:00:00', 'HH:mm:ss'),
                                    moment('11:59:59', 'HH:mm:ss')
                                ]
                            }"
                            format="YYYY-MM-DD HH:mm:ss"
                        />
                    </span>
                </span>
            </div>
            <div class="window1">
                <DHPlayer
                    videoId="realPlayer"
                    :window-type="windowType"
                    ref="dhplayer"
                    :cover-shield-class="['ant-layout-content']"
                    :shieldClass="[
                        'test_drop',
                        'streamTypeClass',
                        'datePickerClass',
                        'recordSourceClass'
                    ]"
                    :request="ajaxRequest"
                    @createSuccess="createSuccess"
                    @realError="realError"
                    @talkError="talkError"
                    @clickWindow="clickWindow"
                    @changeDivision="getDivisionNum"
                    @picCap="picCap"
                    @notifyTalk="notifyTalk"
                ></DHPlayer>
            </div>
            <div class="error-tip" v-show="errorTip">
                错误提示：{{ errorTip }}
            </div>
        </a-col>
    </a-row>
</template>

<script>
import DHPlayer from '../components/DHPlayer'
import api from '../js/factory'
import moment from 'moment'
export default {
    data() {
        return {
            moment,
            modelType: '2', // 1-流地址  2-工程化
            streamType: 1, // 1-主码流 2-辅码流
            recordSource: 2, // 1-全部 2-录像 3-中心
            treeData: [],
            flatTreeData: [], // 扁平化的树
            checkedKeys: [],
            expandedKeys: [],
            selectedKeys: [],
            selectedNodes: [],
            replaceFields: {
                title: 'name'
            },
            timeRanger: [moment().startOf('days'), moment().endOf('days')], // 默认当天
            channel: '',
            channel2: '',
            path: '',
            path3: '',
            path4: '',
            videoType: 'video1',
            currentNum: 0,
            errorTip: '',
            divisionNum: 1, // 当前窗口的分割数量
            isRedirect: false, // true 是代表重定向(拼接的)  false 表示取消重定向(接口返回)
            talkParam: '',
            enableIVS: true,
            isvType: 1,
            realPanControl: null,
            panClloapse: '1',
            windowType: 0,
        }
    },
    components: {
        DHPlayer
    },
    mounted() {
        this.getTree()
    },
    watch: {
        videoType(val, oldVal) {
            this.currentNum = 0
            this.checkedKeys = []
            this.windowType = val === 'video1' ? 0 : 3
        }
    },
    methods: {
        // 创建成功回调
        createSuccess() {
            this.videoType === 'video1' && this.$refs.dhplayer.initPanTilt('dhplayer-pan-tilt')
        },
        // 数组对象去重
        uniqueArr(arr) {
            let map = new Map()
            for (let item of arr) {
                map.set(item.id, item)
            }
            return [...map.values()]
        },
        getTree() {
            api.getTree({
                showEmptyOrgNode: 0,
                type: '001;;1'
            })
                .then(res => {
                    let treeData = [res.value[0]]
                    treeData[0].children = [...res.value.slice(1)]
                    this.expandedKeys = [treeData[0].id]
                    this.treeData = this.generateList(treeData)
                    this.treeData = [...this.treeData]
                    this.flatTreeData = res.value.filter(
                        item => item.nodeType === 'ch'
                    )
                })
                .catch(err => {
                    if (err.code === '27001007') {
                        this.$emit('loginout')
                    }
                })
        },
        loadTreeData(treeNode) {
            let param = {
                checkStat: 1,
                id: treeNode.eventKey,
                showEmptyOrgNode: 0,
                type: '001;;1'
            }
            if (!treeNode.dataRef.children) {
                return
            }
            api.getTree(param)
                .then(res => {
                    treeNode.dataRef.children = this.generateList(res.value)
                    this.flatTreeData = this.uniqueArr(
                        [
                            ...this.flatTreeData,
                            ...treeNode.dataRef.children
                        ].filter(item => item.nodeType === 'ch')
                    )
                })
                .catch(err => {
                    if (err.code === '27001007') {
                        this.$emit('loginout')
                    }
                })
            this.treeData = [...this.treeData]
        },
        /***
         * 循环数组方法
         * @param {Array} data 循环的数组
         ***/
        generateList(data) {
            for (let i = 0; i < data.length; i++) {
                const node = data[i]
                node.id = node.id || node.uniqueMenuCode
                node.key = node.id
                node.parentId =
                    node.pId || node.parentId || node.puniqueMenuCode
                node.isLeaf = !node.isParent
                if (node.isParent && !node.children) {
                    node.children = []
                }
                node.scopedSlots = { icon: 'icon' }
                if (node.nodeType === 'org' || node.nodeType === 'dev') {
                    node.checkable = false
                }
                if (node.nodeType === 'ch' || node.nodeType === 'dev') {
                    node.iconType = node.isOnline
                        ? `https://${sessionStorage.ip}${node.iconType}_online.png`
                        : `https://${sessionStorage.ip}${node.iconType}_offline.png`
                } else {
                    node.iconType = `https://${sessionStorage.ip}${node.iconType}.png`
                }
                if (node.nodeType === 'ch') {
                    node.disabled = !node.isOnline
                }
                if (node.children && node.children.length) {
                    this.generateList(node.children)
                }
            }
            return data
        },
        onExpand(expandedKeys, treeNode) {
            this.expandedKeys = expandedKeys.includes('001')
                ? expandedKeys
                : [...['001'], expandedKeys]
            this.loadTreeData(treeNode.node)
        },
        onSelect(selectedKeys, info) {
            this.selectedNodes = []
            this.selectedKeys = []
            info &&
                info.selectedNodes.forEach(item => {
                    this.selectedNodes.push(item.data.props.dataRef)
                    this.selectedKeys.push({ channelId: item.key })
                })
            if (!selectedKeys[0].includes('$1$0$')) {
                this.$message.error('请选择通道')
                return
            }
            let data = info.node.dataRef
            this.videoType === 'video1'
                ? this.$refs.dhplayer.startReal([
                      {
                          channelId: data.id,
                          cameraType: data.cameraType, // 摄像头类型（用于云台控制）
                          capability: data.capability, // 能力集（用于云台控制）
                          deviceType: data.deviceType, // 设备类型（用于对讲）
                          streamType: this.streamType, // 选择主码流或者辅码流
                          snum: this.currentNum
                      }
                  ])
                : this.$refs.dhplayer.startPlayback([
                      {
                          channelId: data.id, // 通道id
                          name: data.name, // 通道名称
                          startTime: moment(this.timeRanger[0]).format(
                              'yyyy-MM-DD HH:mm:ss'
                          ),
                          endTime: moment(this.timeRanger[1]).format(
                              'yyyy-MM-DD HH:mm:ss'
                          ),
                          recordSource: this.recordSource, // 2-录像 3-中心
                          streamType: this.streamType, //  1-主码流  2-辅码流
                          snum: this.currentNum // 播放窗口
                      }
                  ])
        },
        // 通过通道ID播放实时预览
        realByChannel() {
            let param = this.flatTreeData
                .filter(item => this.checkedKeys.includes(item.id))
                .map((item, index) => {
                    return {
                        channelId: item.id,
                        cameraType: item.cameraType,
                        capability: item.capability,
                        deviceType: item.deviceType,
                        streamType: this.streamType, // 选择主码流或者辅码流
                        snum: this.currentNum + index
                    }
                })
            this.$refs.dhplayer.startReal(param)
        },
        // 实时预览错误提示
        realError(info, err) {
            this.$message.error(`${info.channelId} ${err.desc}`)
        },
        // 选择窗口进行对讲
        talkBySnum() {
            this.$refs.dhplayer.startTalk(this.currentNum)
        },
        // 根据rtsp对讲回调
        notifyTalk({channelId, snum}) {
            console.log('需要对讲的回调', channelId, snum)
        },
        // 对讲错误提示
        talkError(info, err) {
            this.$message.error(`${info.channelId} ${err.desc}`)
        },
        // 通过通道ID播放录像回放
        playbackByChannel() {
            let param = this.flatTreeData
                .filter(item => this.checkedKeys.includes(item.id))
                .map((item, index) => {
                    return {
                        channelId: item.id, // 通道id
                        name: item.name, // 通道名称
                        startTime: moment(this.timeRanger[0]).format(
                            'yyyy-MM-DD HH:mm:ss'
                        ),
                        endTime: moment(this.timeRanger[1]).format(
                            'yyyy-MM-DD HH:mm:ss'
                        ),
                        recordSource: this.recordSource, // 2-录像 3-中心
                        streamType: this.streamType, //  1-主码流  2-辅码流
                        snum: this.currentNum + index // 播放窗口
                    }
                })
            this.$refs.dhplayer.startPlayback(param)
        },
        // 下载录像
        downloadRecord() {
            this.$refs.dhplayer.downloadRecord({
                path: this.path4,
                redirect: this.isRedirect
            })
        },
        //修改url
        changeUrl() {
            if (this.videoType === 'video1') {
                this.$refs.dhplayer.realByUrl({
                    channelId: this.channel,
                    path: this.path,
                    redirect: this.isRedirect
                }, this.currentNum)
            }
            if (this.videoType === 'video2') {
               this.$refs.dhplayer.playbackByUrl(
                    {
                        channelId: this.channel,
                        path: this.path,
                        redirect: this.isRedirect
                    },
                    this.currentNum
                )
            }
        },
        chooseWindow() {
            this.$refs.dhplayer.chooseWindow(this.currentNum)
        },
        // 传入链接地址进行对讲
        talkByUrl() {
            let param = this.talkParam.split(',')
            this.$refs.dhplayer.talkByUrl(
                {
                    path: this.path3,
                    audioType: param[0], // 音频类型 int  0-default 1-PCM 2-G711a 3-AMR 4-G711U 5-G726 6-AAC 7-G722 8-G711
                    audioBit: param[1], // 位数 int   8  16
                    sampleRate: param[2], // 采样频率  8000 16000 32000 48000 8192
                    talkType: 2 // 对讲类型： 1 设备对讲  2通道对讲  目前都是通道对讲
                },
                this.currentNum
            )
        },
        // 控件切换窗口数量时返回前端告知当前多少窗口
        getDivisionNum(v) {
            this.divisionNum = v
        },
        // 修改当前控件展示的窗口数量
        changeDivision() {
            this.$refs.dhplayer.changeDivision(this.divisionNum)
        },
        downloadFile(url, name = new Date().valueOf()) {
            var a = document.createElement('a')
            a.setAttribute('href', url)
            a.setAttribute('download', name)
            a.setAttribute('target', '_blank')
            let clickEvent = document.createEvent('MouseEvents')
            clickEvent.initEvent('click', true, true)
            a.dispatchEvent(clickEvent)
        },
        picCap({ path }) {
            this.downloadFile(path, 'image_' + new Date().valueOf())
        },
        // 点击的窗口
        clickWindow(snum) {
            this.currentNum = snum
        },
        // 录像拖拽后的回调
        switchStartTime() {}
    },
    computed: {
        streamTypeOption() {
            this.streamType = this.videoType === 'video1' ? 1 : 0 
            return this.videoType === 'video1'
                ? [
                      {
                          value: 1,
                          label: '主码流'
                      },
                      {
                          value: 2,
                          label: '辅码流'
                      }
                  ]
                : [
                      {
                          value: 0,
                          label: '所有码流'
                      },
                      {
                          value: 1,
                          label: '主码流'
                      },
                      {
                          value: 2,
                          label: '辅码流'
                      }
                  ]
        },
        maxSnum() {
            let arr = [1, 4, 6, 8, 9, 13, 16, 20, 25, 36, 64]
            let num = 0
            arr.forEach((item, index) => {
                if (this.divisionNum > item) {
                    num = arr[index + 1]
                }
                if (this.divisionNum === item) {
                    num = arr[index]
                }
            })
            return num - 1
        },
        ajaxRequest() {
            return this.videoType === 'video1' ? {
                real: api.fetchRealRtsp,
                talk: api.fetchTalkRtsp,
                stopTalk: api.stopTalk,
                setPtzDirection: api.setPtzDirection,
                setPtzCamera: api.setPtzCamera,
            } : {
                playbackByTime: api.fetchPlaybackByTime,
                playbackByFile: api.fetchPlaybackByFile,
                queryRecord: api.queryRecord
            }
        }
    }
}
</script>

<style>
.videoBox {
    clear: both;
    text-align: left;
    overflow: hidden;
}

.ant-card {
    height: 720px;
    overflow: hidden;
    border-radius: 5px;
}

.window1 {
    width: 100%;
    display: block;
    height: 680px;
    border: 2px solid #2db7f4;
    background-color: #161a1e;
    float: left;
    margin-top: 10px;
}

.error-tip {
    clear: both;
    color: red;
    margin-left: 20px;
}

.videoBox button {
    margin-left: 10px;
    margin-bottom: 10px;
}

.modelTyleCard {
    height: 620px;
}

.option {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    height: 450px;
}

.ods-info {
    display: flex;
    flex-wrap: wrap;
}

.osd-info-item {
    margin-right: 20px;
    margin-bottom: 10px;
}

.ods-info-input {
    width: 200px;
}

.desc-topic {
    font-weight: bold;
    font-size: 16px;
    color: rgb(15, 98, 136);
}

.pan-clloapse {
    position: absolute;
    left: 0;
    width: 100%;
    bottom: 0;
}

.pan-clloapse .ant-collapse-content {
    position: relative;
    height: 240px;
}

#dhplayer-pan-tilt {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 240px;
}
</style>
